package com.founder.bdyx.wxpay.service;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.founder.bdyx.modules.sys.mapper.ApplyInfoMapper;
import com.founder.bdyx.modules.sys.model.ApplyInfo;
import com.founder.bdyx.wxpay.controller.wxpay.WxPayV3Controller;
import com.founder.bdyx.wxpay.domain.WxApiSharingType;
import com.founder.bdyx.wxpay.domain.WxPayV3Bean;
import com.founder.bdyx.wxpay.mapper.PayNoticeInfoMapper;
import com.founder.bdyx.wxpay.mapper.ProfitSharingModelResponseMapper;
import com.founder.bdyx.wxpay.model.PayNoticeInfo;
import com.founder.bdyx.wxpay.model.ProfitSharingModel;
import com.founder.bdyx.wxpay.model.ProfitSharingModelResponse;
import com.founder.bdyx.wxpay.model.Receiver;
import com.ijpay.core.IJPayHttpResponse;
import com.ijpay.core.enums.RequestMethod;
import com.ijpay.core.kit.PayKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.enums.WxDomain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

@Service
public class WxPayV3Service {
    private static final Logger log = LoggerFactory.getLogger(WxPayV3Controller.class);

    @Resource
    WxPayV3Bean wxPayV3Bean;
    @Autowired
    PayNoticeInfoMapper payNoticeInfoMapper;
    @Autowired
    ApplyInfoMapper applyInfoMapper;

    String serialNo;

    @Autowired
    ProfitSharingModelResponseMapper sharingModelResponseMapper;

    public String getSerialNumber() {

        //serialNo = "208DAAE42F98675F897D04DCC1EC1CE1E2EBEF34";
        if (StrUtil.isEmpty(serialNo)) {
            // 获取证书序列号
            X509Certificate certificate = PayKit.getCertificate(FileUtil.getInputStream(wxPayV3Bean.getCertPath()));
            serialNo = certificate.getSerialNumber().toString(16).toUpperCase();

//            System.out.println("输出证书信息:\n" + certificate.toString());
//            // 输出关键信息，截取部分并进行标记
//            System.out.println("证书序列号:" + certificate.getSerialNumber().toString(16));
//            System.out.println("版本号:" + certificate.getVersion());
//            System.out.println("签发者：" + certificate.getIssuerDN());
//            System.out.println("有效起始日期：" + certificate.getNotBefore());
//            System.out.println("有效终止日期：" + certificate.getNotAfter());
//            System.out.println("主体名：" + certificate.getSubjectDN());
//            System.out.println("签名算法：" + certificate.getSigAlgName());
//            System.out.println("签名：" + certificate.getSignature().toString());
        }
        log.info("serialNo:" + serialNo);
        return serialNo;
    }

    /**
     * 请求分账
     * https://api.mch.weixin.qq.com/v3/profitsharing/orders
     * @param noticeInfo 支付通知信息
     * @return
     */
    public String profitShareRequest(PayNoticeInfo noticeInfo) {
        try {
            ProfitSharingModel profitSharingModel = ProfitSharingModel.builder()
                    .appid(wxPayV3Bean.getAppId())
                    .transaction_id(noticeInfo.getTransaction_id())
                    .out_order_no(noticeInfo.getOut_trade_no())
                    .receivers(new ArrayList<Receiver>(){{this.add(
                            new Receiver(wxPayV3Bean.getProfitType(),wxPayV3Bean.getProfitAccount(),null,noticeInfo.getPayer_total()-(noticeInfo.getPayer_total()-1),"分账福利" + noticeInfo.getOut_trade_no())
                    );}})
                    .unfreeze_unsplit(true).build();

            log.info("请求分账参数 {}", JSONUtil.toJsonStr(profitSharingModel));
            IJPayHttpResponse response = WxPayApi.v3(
                    RequestMethod.POST,
                    WxDomain.CHINA.toString(),
                    WxApiSharingType.PROFIT_SHARING_ORDERS.toString(),
                    wxPayV3Bean.getMchId(),
                    getSerialNumber(),
                    null,
                    wxPayV3Bean.getKeyPath(),
                    JSONUtil.toJsonStr(profitSharingModel)
            );
            // 根据证书序列号查询对应的证书来验证签名结果
            boolean verifySignature = WxPayKit.verifySignature(response, wxPayV3Bean.getPlatformCertPath());
            log.info("verifySignature: {}", verifySignature);
            log.info("请求分账响应 {}", response);
            if (verifySignature) {
                if(response.getStatus() != 200) return response.getBody();
                String body = response.getBody();
                /*分账请求记录 profit_sharing_info*/
                ProfitSharingModelResponse sharingModelResponse = JSONUtil.toBean(body, ProfitSharingModelResponse.class);
                sharingModelResponse.setReceiver(sharingModelResponse.getReceivers().get(0));
                sharingModelResponseMapper.saveProfitSharingModelResponse(sharingModelResponse);

                ApplyInfo applyInfo = applyInfoMapper.getByAppId(noticeInfo.getOut_trade_no());
                applyInfo.setSharingFlag(sharingModelResponse.getState());//1、PROCESSING：处理中 2、FINISHED：分账完成
                applyInfoMapper.updateShareFlag(applyInfo);
            }
            return response.getBody();
        } catch (Exception e) {
            log.error("请求分账接口调用失败",e);
        }
        return null;
    }

    /**
     * 查询分账结果
     * https://api.mch.weixin.qq.com/v3/profitsharing/orders/{out_order_no}
     * @param noticeInfo 支付通知信息
     * @return
     */
    public String profitShareResult(PayNoticeInfo noticeInfo) {
        try {

            log.info("查询分账结果参数 {}", JSONUtil.toJsonStr(noticeInfo));
            IJPayHttpResponse response = WxPayApi.v3(
                    RequestMethod.GET,
                    WxDomain.CHINA.toString(),
                    WxApiSharingType.PROFIT_SHARING_ORDERS_RESULT.toString()
                        .replace("OUT_ORDER_NO",noticeInfo.getOut_trade_no())
                        .replace("TRANSACTION_ID",noticeInfo.getTransaction_id()),
                    wxPayV3Bean.getMchId(),
                    getSerialNumber(),
                    null,
                    wxPayV3Bean.getKeyPath(),
                    ""
            );
            // 根据证书序列号查询对应的证书来验证签名结果
            boolean verifySignature = WxPayKit.verifySignature(response, wxPayV3Bean.getPlatformCertPath());
            log.info("verifySignature: {}", verifySignature);
            log.info("查询分账结果响应 {}", response);
            if (verifySignature) {
                if(response.getStatus() != 200) return response.getBody();
                String body = response.getBody();
                /*分账请求记录 profit_sharing_info*/
                ProfitSharingModelResponse sharingModelResponse = JSONUtil.toBean(body, ProfitSharingModelResponse.class);
                sharingModelResponse.setReceiver(sharingModelResponse.getReceivers().get(0));
                sharingModelResponseMapper.saveProfitSharingModelResponse(sharingModelResponse);

                ApplyInfo applyInfo = applyInfoMapper.getByAppId(noticeInfo.getOut_trade_no());
                applyInfo.setSharingFlag(sharingModelResponse.getState());//1、PROCESSING：处理中 2、FINISHED：分账完成
                applyInfoMapper.updateShareFlag(applyInfo);
            }
            return response.getBody();
        } catch (Exception e) {
            log.error("查询分账结果接口调用失败",e);
        }
        return null;
    }

    /**
     * 解冻剩余资金
     * https://api.mch.weixin.qq.com/v3/profitsharing/orders/{out_order_no}
     * @param noticeInfo 支付通知信息
     * @return
     */
    public String profitShareUnfreeze(PayNoticeInfo noticeInfo) {
        try {

            Map<String,String> object = new HashMap<>();
            object.put("transaction_id",noticeInfo.getTransaction_id());
            object.put("out_order_no",noticeInfo.getOut_trade_no());
            object.put("description","解冻全部剩余资金" + noticeInfo.getOut_trade_no());

            log.info("解冻剩余资金参数 {}", JSONUtil.toJsonStr(object));
            IJPayHttpResponse response = WxPayApi.v3(
                    RequestMethod.POST,
                    WxDomain.CHINA.toString(),
                    WxApiSharingType.PROFIT_SHARING_ORDERS_UNFREEZE.toString(),
                    wxPayV3Bean.getMchId(),
                    getSerialNumber(),
                    null,
                    wxPayV3Bean.getKeyPath(),
                    JSONUtil.toJsonStr(object)
            );
            // 根据证书序列号查询对应的证书来验证签名结果
            boolean verifySignature = WxPayKit.verifySignature(response, wxPayV3Bean.getPlatformCertPath());
            log.info("verifySignature: {}", verifySignature);
            log.info("解冻剩余资金响应 {}", response);
            if (verifySignature) {
                if(response.getStatus() != 200) return response.getBody();
                String body = response.getBody();
                /*分账请求记录 profit_sharing_info*/
                ProfitSharingModelResponse sharingModelResponse = JSONUtil.toBean(body, ProfitSharingModelResponse.class);
                sharingModelResponse.setReceiver(sharingModelResponse.getReceivers().get(0));
                sharingModelResponseMapper.saveProfitSharingModelResponse(sharingModelResponse);

                if(sharingModelResponse.getState().equals("FINISHED")){
                    ApplyInfo applyInfo = applyInfoMapper.getByAppId(noticeInfo.getOut_trade_no());
                    applyInfo.setSharingFlag("UNFREEZE");
                    applyInfoMapper.updateShareFlag(applyInfo);
                }
            }
            return response.getBody();
        } catch (Exception e) {
            log.error("解冻剩余资金接口调用失败",e);
        }
        return null;
    }
}
